<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/1/26 0026
 * Time: 17:31
 */
namespace app\manager\model;

use app\common\helper\Obj2Array;
use app\common\model\Model;
use app\manager\model\validate\PermissionValidate;
use Exception;
use think\Db;
use think\Session;

class PermissionModel extends Model {
    const LEVEL_ONE = 1; // 权限等级, 1级为顶级权限项可以拥有子级
    const LEVEL_TWO = 2; // 权限等级，没有子级

    /**
     * 默认的子权限list
     */
    public static function childList() {
        return [
            'update' => '更新',
            'lock' => '锁定',
            'add' => '新增',
            'delete' => '删除',
            //'exl_out' => '导出',
            'view' => '详情',
        ];
    }

    public static function levelList() {
        return [
            self::LEVEL_ONE => '一级权限',
            self::LEVEL_TWO => '二级权限',
        ];
    }

    public static function pidList() {
        $model = new self();
        $list = $model->field(['id', 'name'])->where(['level' => self::LEVEL_ONE, 'status' => self::STATUS_OK])->select();
        if (!empty($list)) {
            $list = Obj2Array::resObject2Array($list);
        }
        return $list;
    }


    /**
     * 获取用户授权
     *
     */
    public function permissionList() {
        // role
        $sessionM = new Session();
        $manager = $sessionM->get('user');
        $managerRoleM = new ManagerRoleModel();
        $role_ids = $managerRoleM->where(['manager_id' => $manager['uid']])->column('role_id');
        if (empty($role_ids)) {
            return [];
        }

        //var_dump($manager);die;
        $permission = $this
            ->alias('p')
            ->join('base_role_permission r', 'r.permission_id = p.id')
            ->where(['p.status' => PermissionModel::STATUS_OK])
            ->where(['r.type' => RolePermissionModel::TYPE_PERMISSION])
            ->where('r.role_id', 'IN',  $role_ids)
            //->order(['m.level'=> 'ASC', 'm.sort' =>  'ASC'])
            ->column('p.route');

        //var_dump($permission);die;
        if (empty($permission)) {
            return [];
        }
        return $permission;
    }

    /**
     *  获取普通权限并进行缓存，注意菜单权限不在此处理也不做缓存
     *
     * @return array|mixed
     * @throws Exception
     */
    public function getPermissionList() {
        $fileCacheM = new PermissionFileCache();
        if (!$permission_route = $fileCacheM->getPermission()) {
            $permission_route = $this->permissionList();
            if (!$fileCacheM->setPermission($permission_route)) {
                throw new Exception('对权限进行缓存失败！');
            }
        }
        return $permission_route;
    }


    /**
     * 新增权限
     *
     * @param $data
     * @return bool
     */
    public function save2($data) {
        $validateM = new PermissionValidate();
        if (!$validateM->check($data)) {
            $this->error = $validateM->getError();
            return false;
        }
        Db::startTrans();
        try {
            // 先将父权限入库获得父级ID
            if (!$this->allowField(true)->save($data)) {
                throw new \think\Exception('保存父级权限失败');
            }
            $p_id = $this->getLastInsID();

            // 子权限处理
            $list = [];
            if (!empty($data['child'])) {
                $childs = $data['child'];
                // 默认的子权限
                $default_child = self::childList();
                $default_child_keys = array_keys($default_child);
                // 父权限的路由前缀
                $prefix_route = $this->findPrefixRoute($data['route']);
                foreach ($childs as $c) {
                    if (!in_array($c, $default_child_keys)) {
                        throw new \think\Exception('子权限不存在');
                    }
                    $child = [
                        'name' => $default_child[$c],
                        'route' => $prefix_route . $c,
                        'level' => self::LEVEL_TWO,
                        'status' => self::STATUS_OK,
                        'p_id' => $p_id,
                        'created_time' => date('Y-m-d H:i:s', time()),
                        'updated_time' => date('Y-m-d H:i:s', time()),
                    ];
                    $list[] = $child;
                }
                //var_dump($child);die;
                // 子权限入库
                if (!$this->insertAll($list)) {
                    throw new \think\Exception('子权限入库失败');
                }
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $this->error = $e->getMessage();
            return false;
        }
        return true;
    }

    /***
     * 更新权限
     *
     * @param $data
     * @return bool
     */
    public function update_2($data) {
        $validateM = new PermissionValidate();
        if (!$validateM->check($data)) {
            $this->error = $validateM->getError();
            return false;
        }
        Db::startTrans();
        try {
            // 默认的子权限
            $default_child = self::childList();
            $default_child_keys = array_keys($default_child);
            // 删除原有默认子权限中的已经弃选的默认子权限
            $delete_child = array_diff(array_flip($default_child), $data['child']);
            if (!empty($delete_child)) {
                $delete_child = array_values(array_flip($delete_child));
                $this->where(['p_id' => $data['id']])->where('name', 'IN', $delete_child)->delete();
            }

            // 先将父权限入库获得父级ID
            if (!$this->allowField(true)->save($data, ['id' => $data['id']])) {
                throw new \think\Exception('更新父级权限失败');
            }
            // 子权限处理
            $list = [];
            if (!empty($data['child'])) {
                $childs = $data['child'];
                // 父权限的路由前缀
                $prefix_route = $this->findPrefixRoute($data['route']);
                foreach ($childs as $c) {
                    if (!in_array($c, $default_child_keys)) {
                        throw new \think\Exception('子权限不存在');
                    }
                    $child = [
                        'name' => $default_child[$c],
                        'route' => $prefix_route . $c,
                        'level' => self::LEVEL_TWO,
                        'status' => self::STATUS_OK,
                        'p_id' => $data['id'],
                        'created_time' => date('Y-m-d H:i:s', time()),
                        'updated_time' => date('Y-m-d H:i:s', time()),
                    ];
                    // 过滤已经入库的子权限
                    if (!empty($this->where(['route' => $prefix_route . $c])->find())) {
                        continue;
                    }
                    $list[] = $child;
                }
                // 子权限入库
                if (!empty($list)) {
                    if (!$this->insertAll($list)) {
                        throw new \think\Exception('更新子权限失败!');
                    }
                }

            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $this->error = $e->getMessage();
            return false;
        }
        return true;
    }



    /**
     * 获取子权限
     *
     * @param $pid
     * @return array
     */
    public function getChild($pid) {
        $child = $this->where(['p_id' => $pid])->column('route');
        $list = [];
        if (!empty($child)) {
            foreach ($child as $item) {
                $last_pos = strrpos($item, '/');
                $str = substr($item, $last_pos+1);
                $list[] = $str;
            }
        }
        return $list;
    }

    private function findPrefixRoute($route) {
        $last_pos = strrpos($route, '/');
        return $str = substr($route, 0, $last_pos+1);
    }

}